package com.yunda.AJDeviceService.utils;

import com.yunda.AJDeviceService.common.exception.CustomException;
import jodd.util.StringUtil;
import org.apache.commons.codec.binary.Hex;

import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.Random;
import java.util.regex.Pattern;

/**
 *
 * @author zoulin
 * @email zoulin8715@yundasys.com
 * @date 2019-08-14 16:37:37
 */
@SuppressWarnings("ALL")
public class DataUtils {

	private static Pattern NUMBER_PATTERN = Pattern.compile("^[-\\+]?[\\d]*$");
	private static String DEFAULT_DECIMAL_FORMAT = "%.2f";

	public static String toStringNumFormat(Object obj){
		return toStringNumFormat(obj, DEFAULT_DECIMAL_FORMAT);
	}

	public static String toStringNumFormat(Object obj,String format){
		if(obj==null){
			return "";
		}
		double val = toDouble(obj);
		String vatStr = "";
		if(val == 0){
			vatStr = "0";
		}else{
			vatStr = String.format(format,toDouble(obj));
		}
		return vatStr;
	}

	/**
	 * 获取一个文件的md5值(可处理大文件)
	 * @return md5 value
	 */
	public static String getMD5(File file) {
		FileInputStream fileInputStream = null;
		try {
			MessageDigest MD5 = MessageDigest.getInstance("MD5");
			fileInputStream = new FileInputStream(file);
			byte[] buffer = new byte[1024];
			int length;
			while ((length = fileInputStream.read(buffer)) != -1) {
				MD5.update(buffer, 0, length);
			}
			return new String(Hex.encodeHex(MD5.digest()));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				if (fileInputStream != null){
					fileInputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static String toString(Object obj){
		if(obj==null){
			return "";
		}
		return obj.toString();
	}

    /**
     * Object转BigDecimal类型-王雷-2018年5月14日09:56:26
     *
     * @param value 要转的object类型
     * @return 转成的BigDecimal类型数据
     */
    public static BigDecimal toBigDecimal(Object value) {
        BigDecimal ret = null;
        if (value != null) {
            if (value instanceof BigDecimal) {
                ret = (BigDecimal) value;
            } else if (value instanceof String) {
                ret = new BigDecimal((String) value);
            } else if (value instanceof BigInteger) {
                ret = new BigDecimal((BigInteger) value);
            } else if (value instanceof Number) {
                ret = new BigDecimal(((Number) value).doubleValue());
            } else {
                throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " into a BigDecimal.");
            }
        }
        return ret;
    }

	public static double toDouble(Object obj){
		if(StringUtils.isBlank(toString(obj))){
			return 0;
		}

		return Double.valueOf(obj.toString());
	}
	
	public static float toFloat(Object obj){
		if(StringUtils.isBlank(toString(obj))){
			return 0;
		}
		
		return Float.valueOf(obj.toString());
	}
	
	public static int toInt(Object obj){
		if(StringUtils.isBlank(toString(obj))){
			return 0;
		}
		
		return Integer.valueOf(obj.toString());
	}

	public static long toLong(Object obj){
		if(StringUtils.isBlank(toString(obj))){
			return 0;
		}

		return Long.valueOf(obj.toString());
	}
	
	public static long randomLong(int len){
		StringBuffer sb = new StringBuffer();
		Random random = new Random();
		for(int i = 0 ; i < len ; i++){
			sb.append(String.valueOf(random.nextInt(10)));
		}
		
		return Long.valueOf(sb.toString());
	}

	/**
	 * 去除尾数0
	 * @param s
	 * @return
	 */
	public static String stripTrailingZeros(String s) {
		if (StringUtils.isBlank(s)) {
			return "";
		}
		String zero = "0";
		String dh = ".";
		if (s.endsWith(zero) && s.indexOf(dh) > 0) {
			// 去掉后面无用的零
			s = s.replaceAll("0+?$", "");
			//如小数点后面全是零则去掉小数点
			s = s.replaceAll("[.]$", "");
		}
		return s;
	}

	/**
	 * 格式化数字并去除尾数0，默认保留2位小数
	 * @param obj
	 * @return
	 */
	public static String toStringNumFormatStripTrailingZeros(Object obj){
		return toStringNumFormatStripTrailingZeros(obj, DEFAULT_DECIMAL_FORMAT);
	}

	/**
	 * 格式化数字并去除尾数0
	 * @param obj
	 * @param format
	 * @return
	 */
	public static String toStringNumFormatStripTrailingZeros(Object obj,String format){
		String objStr = toString(obj);
		if (StringUtils.isBlank(objStr)) {
			return "";
		}
		return stripTrailingZeros(toStringNumFormat(objStr, format));
	}

	/**
	 * 得分计算															20210223版本
	 * @param worstVal			最差值（-1表示无最差值）					-版本弃用
	 * @param bottomGuardVal	保底值
	 * @param targetVal			目标值
	 * @param challengeVal		挑战值									-版本弃用
	 * @param actualVal			实际值
	 * @param maxWeightVal		最大权重
	 * @param challengeRate		挑战率=（考核类型挑战系数-1）*100			-版本弃用
	 */
	public static float calculateScore(float worstVal,float bottomGuardVal,float targetVal,float challengeVal,float actualVal,float maxWeightVal,float challengeRate ){
		float score = 0f;
		//得分
		if (targetVal < bottomGuardVal) {
			//左分支
			if (actualVal < bottomGuardVal) {
				if (actualVal < targetVal) {
					score = maxWeightVal * 100;
				} else {
					score = maxWeightVal * 100 * (actualVal - bottomGuardVal) / (targetVal - bottomGuardVal);
				}
			}
		} else if (targetVal > bottomGuardVal) {
			//右分支
			if (actualVal > bottomGuardVal) {
				if (actualVal > targetVal) {
					score = maxWeightVal * 100;
				} else {
					score = maxWeightVal * 100 * (actualVal - bottomGuardVal) / (targetVal - bottomGuardVal);
				}
			}
		}

		return score;
	}

	// /**
	//  * 得分计算
	//  * @param worstVal			最差值（-1表示无最差值）
	//  * @param bottomGuardVal	保底值
	//  * @param targetVal			目标值
	//  * @param challengeVal		挑战值
	//  * @param actualVal			实际值
	//  * @param maxWeightVal		最大权重
	//  * @param challengeRate		挑战率=（考核类型挑战系数-1）*100
	//  */
	/*public static float calculateScore(float worstVal,float bottomGuardVal,float targetVal,float challengeVal,float actualVal,float maxWeightVal,float challengeRate ){
		//得分
		float score = 0f;
		//-1表示无最差值
		float lastVal = -1f;
		//是否已经计算
		boolean calculated = true;
		//逆序
		if (challengeVal < targetVal && targetVal < bottomGuardVal) {
			//无最差值
			if (floatEquals(worstVal,lastVal)) {
				if (actualVal < bottomGuardVal) {
					calculated = false;
				}
			//有最差值
			} else {
				if (actualVal >= worstVal) {
					score = -maxWeightVal * 100;
				} else if (actualVal >= bottomGuardVal) {
					score = -maxWeightVal * 100 * (actualVal - bottomGuardVal) / (worstVal - bottomGuardVal);
				} else {
					calculated = false;
				}
			}
			//还没计算
			if (!calculated) {
				if (actualVal >= targetVal) {
					score = maxWeightVal * 100 * (actualVal - bottomGuardVal) / (targetVal - bottomGuardVal);
				} else if (actualVal >= challengeVal) {
					score = maxWeightVal * 100 + maxWeightVal * challengeRate * (actualVal - targetVal) / (challengeVal - targetVal);
				} else {
					score = maxWeightVal * 100 + challengeRate * maxWeightVal;
				}
			}
		//顺序
		} else if (challengeVal > targetVal && targetVal > bottomGuardVal) {
			//无最差值
			if (floatEquals(worstVal,lastVal)) {
				if (actualVal > bottomGuardVal) {
					calculated = false;
				}
			//有最差值
			} else {
				if (actualVal <= worstVal) {
					score = -maxWeightVal * 100;
				} else if (actualVal <= bottomGuardVal) {
					score = -maxWeightVal * 100 * (actualVal - bottomGuardVal) / (worstVal - bottomGuardVal);
				} else {
					calculated = false;
				}
			}
			//还没计算
			if (!calculated) {
				if (actualVal <= targetVal) {
					score = maxWeightVal * 100 * (actualVal - bottomGuardVal) / (targetVal - bottomGuardVal);
				} else if (actualVal <= challengeVal) {
					score = maxWeightVal * 100 + maxWeightVal * challengeRate* (actualVal - targetVal) / (challengeVal - targetVal);
				} else {
					score = maxWeightVal * 100 + challengeRate * maxWeightVal;
				}
			}
		//其他，挑目保差顺序规则不正确
		} else {
			score = 0f;
		}
		return score;
	}*/
	
	public static String numToCn(String from){
		String to = "";
		if(StringUtils.isNotBlank(from)){
			to = from.replace("1", "一")
					.replace("2", "二")
					.replace("3", "三")
					.replace("4", "四")
					.replace("5", "五")
					.replace("6", "六")
					.replace("7", "七")
					.replace("8", "八")
					.replace("9", "九")
					.replace("0", "零");
		}
		return to;
	}

    /**
     * 除法
     * @param
     * @return
     */
    public static String divideValue(String value,Integer days) {
        BigDecimal bi1 = new BigDecimal(value);
        BigDecimal bi2 = new BigDecimal(days);
        BigDecimal divide = bi1.divide(bi2, 5,BigDecimal.ROUND_HALF_UP);
        //todo 优化需日均单位为万
        BigDecimal bi3 = new BigDecimal(10000);
        BigDecimal b = divide.multiply(bi3);
        return subValue(b.toString());
    }

    /**
     * 除法
     * @param
     * @return
     */
    public static String avgValue(String value,Integer days) {
        BigDecimal bi1 = new BigDecimal(value);
        BigDecimal bi2 = new BigDecimal(days);
        BigDecimal divide = bi1.divide(bi2, 5,BigDecimal.ROUND_HALF_UP);
        return divide.toString();
    }

    /**
     * 转换后的值:整数不保留小数点，其他的保留一位小数（四舍五入）
     * @param
     * @return
     */
    public static String subValue(String str){
        String value = str;
        String fix = "00000";
        if(StringUtils.isNotBlank(str)){
            boolean b = isNumeric(str);
            if(b){
                value = str;
            }else{
                String sub = str.substring(str.lastIndexOf(".")+1,str.length());
                if(fix.equals(sub)){
                    value = str.substring(0,str.lastIndexOf("."));
                }else{
                    BigDecimal bd = new BigDecimal(value);
                    bd = bd.setScale(0,BigDecimal.ROUND_HALF_UP);
                    value = bd.toString();
                }
            }
        }
        return value;
    }

    /**
     * 判断是否为整数
     * @param str 传入的字符串
     * @return 是整数返回true,否则返回false
     */
    public static boolean isNumeric(String str) {
		if (str == null) {
			return false;
		}
		return NUMBER_PATTERN.matcher(str).matches();
    }

    /**
     * 除法(百分数,保留一位小数)
     * @param
     * @return
     */
    public static BigDecimal divideValueOne(BigDecimal v1,BigDecimal v2) {
        BigDecimal value =v1.divide(v2, 10,BigDecimal.ROUND_HALF_UP)
                .multiply(new BigDecimal(100)).setScale(1,BigDecimal.ROUND_HALF_UP);
        return value;
    }

    /**
     * 保留一位小数
     * @param
     * @return
     */
    public static double getValueOne(Double v1) {
        BigDecimal bi1 = BigDecimal.valueOf(v1.doubleValue());
        return bi1.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 校验字符参数长度，限制50
     * @param src
     */
    public static void checkParamsLength(Object... src){
        for (Object o : src) {
            if (DataUtils.toString(o).length() > 50) {
                throw new CustomException("长度限制50");
            }
        }
    }

    /**
     * 校验内容参数长度，限制5000
     * @param src
     */
    public static void checkContentLength(Object... src){
        for (Object o : src) {
            if (DataUtils.toString(o).length() > 5000) {
                throw new CustomException("长度限制5000");
            }
        }
    }


	/**
	 * 版本号比较
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static int compareVersion(String v1, String v2) {
		if (v1.equals(v2)) {
			return 0;
		}
		String[] version1Array = v1.split("[._]");
		String[] version2Array = v2.split("[._]");
		int index = 0;
		int minLen = Math.min(version1Array.length, version2Array.length);
		long diff = 0;

		while (index < minLen
				&& (diff = Long.parseLong(version1Array[index])
				- Long.parseLong(version2Array[index])) == 0) {
			index++;
		}
		if (diff == 0) {
			for (int i = index; i < version1Array.length; i++) {
				if (Long.parseLong(version1Array[i]) > 0) {
					return 1;
				}
			}

			for (int i = index; i < version2Array.length; i++) {
				if (Long.parseLong(version2Array[i]) > 0) {
					return -1;
				}
			}
			return 0;
		} else {
			return diff > 0 ? 1 : -1;
		}
	}

    /**
     * 校验日期字符串是否合法
     *
     * @param dateStr 传入日期格式的字符串
     * @return
     */
    public static boolean checkDateformat(String dateStr) {
        /**
         * YYYY-MM-DD
         */
        String regex = "((19|20)[0-9]{2})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])";
        return Pattern.compile(regex).matcher(dateStr).matches();

    }

	/**
	 * 截取过长字符串
	 * @param len
	 * @param str
	 * @return
	 */
    public static String getShortStr(int len,String str){
    	if(StringUtil.isNotBlank(str)){
    		if(str.length()>len){
    			str = str.substring(0, len);
			}
		}

    	return str;
	}

    /**
     *
     * @Title : filter
     * @Type : FilterStr
     * @date : 2020年07月10日 下午15:15:22
     * @Description : 过滤出字母、数字和中文
     * @param character
     * @return
     */
    public static boolean filter(String character)
    {
        String regex ="^[A-Za-z\\d\\u4E00-\\u9FA5]+$";
        return Pattern.compile(regex).matcher(character).matches();
    }

	/**
	 * 浮点数之间的等值判断，基本数据类型不能用==来比较，包装数据类型不能用equals来判断。
	 * 浮点数采用“尾数+阶码”的编码方式，类似于科学计数法的“有效数字+指数”的表示方式。
	 * 二进制无法精确表示大部分的十进制小数，具体原理参考《码出高效》
	 * @param a
	 * @param b
	 * @return
	 */
    public static boolean floatEquals(float a,float b){
		float diff = 1e-6f;
		return Math.abs(a - b) < diff;
	}

	/**
	 * 浮点数之间的等值判断，基本数据类型不能用==来比较，包装数据类型不能用equals来判断。
	 * 浮点数采用“尾数+阶码”的编码方式，类似于科学计数法的“有效数字+指数”的表示方式。
	 * 二进制无法精确表示大部分的十进制小数，具体原理参考《码出高效》
	 * @param a
	 * @param b
	 * @return
	 */
	public static boolean doubleEquals(double a,double b) {
		double diff = 1e-6;
		return Math.abs(a - b) < diff;
	}

	public static Object toObject(byte[] bytes) throws Exception{
		Object obj = null;
		ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
		ObjectInputStream ois = new ObjectInputStream(bis);
		obj = ois.readObject();
		ois.close();
		bis.close();
		return obj;
	}

	public static byte[] toByteArray(Object obj) throws Exception{
		byte[] bytes = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bos);
		oos.writeObject(obj);
		oos.flush();
		bytes = bos.toByteArray();
		oos.close();
		bos.close();
		return bytes;
	}

    /**
     * 去除无效的0
     *
     * @param s1
     * @return
     */
    public static String delZero(String s1) {
        if (s1.indexOf(".") > 0) {
            s1 = s1.replaceAll("0+?$", "");//去掉多余的0
            s1 = s1.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s1;
    }
	public static String toString(Integer num){
		if(num==null){
			return "";
		}
		return String.valueOf(num);
	}


	public static void main(String[] args) {
		float v = toInt("");
		System.out.println("v = " + v);
		// System.out.println((0.05f-0.06f)/(0.04f-0.06f)*15);
    	//举例说明：以“目标>保底”为例
		// 目标6%，保底4%；权重15%
		// （1）实际值为3%时，实际值≤保底值，得分为0
		// （2）实际值为5%时，实际值>保底值&&实际值≤目标值，得分为15%*100*（5%-4%）/
		// （6%-4%）=7.5
		// （3）实际值为7%时，得分为15%*100=15
		System.out.println(calculateScore(0f,0.06f,0.04f,0f,0.03f,0.15f,0f));//15
		System.out.println(calculateScore(0f,0.06f,0.04f,0f,0.05f,0.15f,0f));//7.5
		System.out.println(calculateScore(0f,0.06f,0.04f,0f,0.07f,0.15f,0f));//0

		System.out.println(calculateScore(0f,0.04f,0.06f,0f,0.03f,0.15f,0f));//0
		System.out.println(calculateScore(0f,0.04f,0.06f,0f,0.05f,0.15f,0f));//7.5
		System.out.println(calculateScore(0f,0.04f,0.06f,0f,0.07f,0.15f,0f));//15

//		System.out.println(DataUtils.compareVersion("0.0.0","1.1.0"));
//		System.out.println(DataUtils.compareVersion("1.2.0.2","1.1.0.2"));
//		System.out.println(DataUtils.compareVersion("1.2.1.2","1.2.1"));
//		System.out.println(DataUtils.compareVersion("1.2.1.2","1.2.2.2"));

//		System.out.println("V1.3.0".replace("V",""));
//
//        System.out.println("校验"+filter("1是什么\uD83D\uDE02\uD83D\uDE0A"));

//        System.out.println("日均: "+divideValue("-2.3",30));
//		double dis = 1e-6;
//		double d1 = 0.0000001d;
//		double d2 = 0d;
//		System.out.println(Math.abs(d1 - d2) < dis);
//		System.out.println(d1==d2);
//
//		System.out.println(DataUtils.floatEquals(-1f,-1f));

		/*double a = 0.1d-0.09d;
		double b = 0.09d-0.08d;
		System.out.println(a==b);

		float g = 7f-6f;
		float h = 8f-7f;
		System.out.println(g==h);
		System.out.println(doubleEquals(g,h));*/
/*		Integer a = -128;
		Integer b = -128;
		Integer c = -129;
		Integer d = -129;

		System.out.println(a==b);
		System.out.println(c==d);


		Integer a = 127;
		Integer b = 127;
		Integer c = 128;
		Integer d = 128;

		System.out.println(a==b);
		System.out.println(c==d);*/


		/*StringBuffer sb = new StringBuffer("");
		sb.append("hq");
		sb.append(",area_1");
		sb.append(",area_2");
		sb.append(",area_3");
		sb.append(",area_4");
		sb.append(",area_5");
		sb.append(",area_6");
		sb.append(",prov_110001");
		sb.append(",prov_120000");
		sb.append(",prov_130001");
		sb.append(",prov_140000");
		sb.append(",prov_150000");
		sb.append(",prov_210000");
		sb.append(",prov_220000");
		sb.append(",prov_230000");
		sb.append(",prov_310000");
		sb.append(",prov_320001");
		sb.append(",prov_320002");
		sb.append(",prov_330001");
		sb.append(",prov_330002");
		sb.append(",prov_340000");
		sb.append(",prov_350000");
		sb.append(",prov_360000");
		sb.append(",prov_370000");
		sb.append(",prov_410000");
		sb.append(",prov_420000");
		sb.append(",prov_430000");
		sb.append(",prov_440001");
		sb.append(",prov_440002");
		sb.append(",prov_440003");
		sb.append(",prov_450000");
		sb.append(",prov_460000");
		sb.append(",prov_500000");
		sb.append(",prov_510000");
		sb.append(",prov_520000");
		sb.append(",prov_530000");
		sb.append(",prov_540000");
		sb.append(",prov_610000");
		sb.append(",prov_620000");
		sb.append(",prov_630000");
		sb.append(",prov_640000");
		sb.append(",prov_650000");
		sb.append(",report_test");
		sb.append(",abac_app_user");
		sb.append(",hq_business");
		sb.append(",prov_check");
		sb.append(",hr_app_user");
		sb.append(",fb_app_user");
		sb.append(",wg_90148152");
		sb.append(",wg_90064447");
		sb.append(",wg_21000010");
		sb.append(",wg_90141245");
		sb.append(",wg_90165308");
		sb.append(",wg_90178968");
		sb.append(",wg_90148876");
		sb.append(",wg_90148879");
		sb.append(",wg_90129583");
		sb.append(",wg_90001064");
		sb.append(",wg_90001010");
		sb.append(",wg_90103827");
		sb.append(",wg_90025832");
		sb.append(",wg_90038489");
		sb.append(",wg_90009885");
		sb.append(",wg_90169344");
		sb.append(",wg_90003198");
		sb.append(",wg_90000119");
		sb.append(",wg_90002034");
		sb.append(",wg_90127272");
		sb.append(",wg_90023976");
		sb.append(",wg_90171139");
		sb.append(",wg_90177884");
		sb.append(",wg_90006849");
		sb.append(",wg_90105731");
		sb.append(",wg_90107476");
		sb.append(",wg_90010090");
		sb.append(",wg_90127430");
		sb.append(",wg_90059427");
		sb.append(",wg_90031564");

		String str  = sb.toString();
		System.out.println(str.length()*3);*/

	}

}


